package com.yida.gwj.common.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yida.common.core.constant.CacheConstants;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.DateUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.redis.service.RedisService;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.gwj.common.domain.GwjBaseCommunity;
import com.yida.gwj.common.domain.dto.GwjBaseCommunityDTO;
import com.yida.gwj.common.domain.dto.GwjBaseCommunityListDTO;
import com.yida.gwj.common.domain.request.GwjBaseBuildRequest;
import com.yida.gwj.common.domain.request.GwjBaseCommunityQueryRequest;
import com.yida.gwj.common.mapper.GwjBaseCommunityMapper;
import com.yida.gwj.common.service.IGwjBaseCommunityService;
import com.yida.system.api.domain.SysArea;

/**
 * 基础数据（小区信息）Service业务层处理
 *
 * @author lqq
 * @date 2022-11-14
 */
@Service
public class GwjBaseCommunityServiceImpl implements IGwjBaseCommunityService {

    private static final Logger log = LoggerFactory.getLogger(GwjBaseCommunityServiceImpl.class);

    @Autowired
    private GwjBaseCommunityMapper communityMapper;

    @Autowired
    private RedisService redisService;

    // 地区列表
    public static final String AREA_LIST = "area.list";

    // 街道
    public static final String STREET = "street";

    /**
     * 查询基础数据（小区信息）
     *
     * @param id 基础数据（小区信息）主键
     * @return 基础数据（小区信息）
     */
    @Override
    public GwjBaseCommunity selectGwjBaseCommunityByGwjBaseCommunityId(Long id) {
        return communityMapper.selectGwjBaseCommunityByGwjBaseCommunityId(id);
    }

    /**
     * 获取小区详细信息(计算面积等信息) lqq
     *
     * @param buildRequest 请求参数
     * @return 基础数据（小区信息）
     */
    @Override
    public GwjBaseCommunityDTO selectGwjBaseCommunityDetail(GwjBaseBuildRequest buildRequest) {
        return communityMapper.selectGwjBaseCommunityDetail(buildRequest);
    }

    /**
     * 查询基础数据（小区信息）列表
     *
     * @param community 基础数据（小区信息）
     * @return 基础数据（小区信息）
     */
    @Override
    public List<GwjBaseCommunity> selectCommunityList(GwjBaseCommunity community) {
        return communityMapper.selectCommunityList(community);
    }

    /**
     * 新增基础数据（小区信息）
     *
     * @param community 基础数据（小区信息）
     * @return 结果
     */
    @Override
    public int insertGwjBaseCommunity(GwjBaseCommunity community) {
        community.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        community.setCreateTime(DateUtils.getNowDate());
        return communityMapper.insertGwjBaseCommunity(community);
    }

    /**
     * 修改基础数据（小区信息）
     *
     * @param community 基础数据（小区信息）
     * @return 结果
     */
    @Override
    public int updateGwjBaseCommunity(GwjBaseCommunity community) {
        community.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        community.setUpdateTime(DateUtils.getNowDate());
        return communityMapper.updateGwjBaseCommunity(community);
    }

    /**
     * 删除基础数据（小区信息）信息
     *
     * @param id 基础数据（小区信息）主键
     * @return 结果
     */
    @Override
    public int deleteGwjBaseCommunityByGwjBaseCommunityId(Long id) {
        return communityMapper.deleteGwjBaseCommunityByGwjBaseCommunityId(id);
    }

    /******************* 新增方法保留区 ******************/

    @Override
    public List<GwjBaseCommunity> selectGwjBaseCommunityList(GwjBaseCommunity community) {
        // return communityMapper.selectGwjBaseCommunityList(community);
        // return communityMapper.selectCommunityList(community);
        return communityMapper.selectGwjBaseCommunityList(community);
    }

    @Override
    public GwjBaseCommunity selectGwjBaseCommunityByGwjBaseCommunityName(String communityName) {
        return communityMapper.selectGwjBaseCommunityByGwjBaseCommunityName(communityName);
    }

    @Override
    public int insertImportGwjBaseCommunity(GwjBaseCommunity gwjBaseCommunity) {
        // 设定为自定义导入参数
        gwjBaseCommunity.setImportFlag("1");
        return communityMapper.insertImportGwjBaseCommunity(gwjBaseCommunity);
    }

    @Override
    public int updateImportGwjBaseCommunity(GwjBaseCommunity gwjCommCommunity) {
        return communityMapper.updateImportGwjBaseCommunity(gwjCommCommunity);
    }

    /**
     * 批量删除基础数据（小区信息）
     *
     * @param ids 需要删除的基础数据（小区信息）主键
     * @return 结果
     */
    @Override
    public int deleteGwjBaseCommunityByGwjBaseCommunityIds(Long[] ids) {
        return communityMapper.deleteGwjBaseCommunityByGwjBaseCommunityIds(ids);
    }

    /* 
     * 根据地区查询项目，返回结构树 
     * 
     * 20230715
     */
    @Override
    public JSONArray queryCommunityList(GwjBaseCommunity gwjBaseCommunity) {
        Long areaId = gwjBaseCommunity.getAreaId();
        // 大于0根据ID进行查询，否则查询全部
        try {
            JSONArray jsonArray = areaId > 0 ? queryCommunityListByAreaId(gwjBaseCommunity) : queryCommunityListAllArea(gwjBaseCommunity);
            return jsonArray;
        } catch (Exception e) {
            log.error("获取数据异常：" + e);
            throw new ServiceException("获取数据异常：" + e.getMessage());
        }
    }

    /**
     * 非areaId情况下查询关联性所有数据
     * 
     * @param gwjBaseCommunity
     * @return
     */
    private JSONArray queryCommunityListAllArea(GwjBaseCommunity gwjBaseCommunity) throws Exception {
        JSONArray jsonArray = new JSONArray();
        Long areaId = gwjBaseCommunity.getAreaId();
        if (0 == areaId) {
            // 反向查询
            // 2查询项目数据,查询全部区域下的信息
            gwjBaseCommunity.setAreaId(null);
            List<GwjBaseCommunity> gwjBaseCommunityList = selectCommunityList(gwjBaseCommunity);
            if (StringUtils.isNull(gwjBaseCommunityList) || gwjBaseCommunityList.size() == 0) {
                // 数据空返回空集合
                return jsonArray;
            }
            // 街道ID=项目集合
            Map<Long, List<Map<String, Object>>> communityMap = communityListToMap(gwjBaseCommunityList, "xm");// xm=项目
            // 获取默认地区集合信息
            // 默认集合
            JSONObject defaultJson = new JSONObject();
            // 获取地区集合
            List<SysArea> areas = redisService.getCacheObject(getCacheKey(AREA_LIST));
            // 转换首个地区和对应查询地区为map
            // Map<Long, String> areasMap = areas.stream().filter(e -> e.getAreaId() == 1 || (e.getAreaId() == areaId &&
            // e.getAreaType() == 2)).collect(Collectors.toMap(SysArea::getAreaId, SysArea::getAreaName));
            Map<Long, String> areasMap = areas.stream().filter(e -> e.getAreaId() == 1 || (e.getAreaType() == 2)).collect(Collectors.toMap(SysArea::getAreaId, SysArea::getAreaName));
            defaultJson.put("id", 1L);
            defaultJson.put("index", "s1");// 为避免前端使用树结构出现重复数字数据，增加英文用于区别级别 s=市
            defaultJson.put("label", areasMap.get(1L));

            // 获取街道树结构
            List<SysArea> streets = redisService.getCacheObject(getCacheKey(STREET));
            Map<Long, SysArea> streetsMap = streets.stream().collect(Collectors.toMap(SysArea::getAreaId, Function.identity(), (oldValue, newValue) -> newValue));
            // areaJson
            // Map<Long, JSONObject> areaResultMap = new HashMap<Long, JSONObject>();
            // Map<Long, JSONObject> areaResultMap =
            // areas.stream().filter(e->(e.getAreaType()==2)).collect(Collectors.toMap(SysArea::getAreaId,
            // Function.identity(),(oldValue, newValue) -> JSONObject.from(newValue) ));
            Map<Long, JSONObject> areaResultMap = areas.stream().filter(e -> (e.getAreaType() == 2)).collect(Collectors.toMap(SysArea::getAreaId, SysArea -> new JSONObject()));
            // 项目集合
            // JSONArray communityJsonArray = new JSONArray();
            Set<Long> streetIds = streetsMap.keySet();
            for (Long streetId : streetIds) {
                JSONObject json = new JSONObject();
                SysArea sysArea = streetsMap.get(streetId);
                List<Map<String, Object>> streetCommunitys = communityMap.get(streetId);
                if (StringUtils.isEmpty(streetCommunitys) || streetCommunitys.size() == 0) {
                    // 空直接跳过
                    continue;
                }
                json.put("id", streetId);
                json.put("index", "jd" + streetId);// jd=街道
                json.put("label", sysArea.getAreaName());
                json.put("children", streetCommunitys);
                // communityJsonArray.add(json);
                JSONObject areaJson = areaResultMap.get(sysArea.getParentId());
                if (!areaJson.containsKey("children")) {
                    areaJson.put("children", new JSONArray());
                }
                JSONArray communityJsonArray = areaJson.getJSONArray("children");
                communityJsonArray.add(json);
                areaJson.put("children", communityJsonArray);
            }
            // 查询地区集合
            JSONArray areaArray = new JSONArray();
            // 根据地区循环组建数据
            for (Long id : areasMap.keySet()) {
                JSONObject areaJson = areaResultMap.get(id);
                if (areaJson != null && !areaJson.isEmpty()) {
                    areaJson.put("id", id);
                    areaJson.put("index", "xq" + id);// 为避免前端使用树结构出现重复数字数据，增加英文用于区别级别 xq=县区
                    areaJson.put("label", areasMap.get(id));
                    areaArray.add(areaJson);
                }
            }
            defaultJson.put("children", areaArray);
            jsonArray.add(defaultJson);
        }
        return jsonArray;
    }

    /**
     * 20210102
     * 
     * hmh
     * 
     * 根据areaId进行查询
     * 
     * @param gwjBaseCommunity
     * @return
     */
    private JSONArray queryCommunityListByAreaId(GwjBaseCommunity gwjBaseCommunity) throws Exception {
        JSONArray jsonArray = new JSONArray();
        Long areaId = gwjBaseCommunity.getAreaId();
        if (StringUtils.isNull(gwjBaseCommunity.getAreaId())) {
            throw new ServiceException("查无地区，请选择后查询!");
        }
        // 默认集合
        JSONObject defaultJson = new JSONObject();
        // 获取地区集合
        List<SysArea> areas = redisService.getCacheObject(getCacheKey(AREA_LIST));
        // 转换首个地区和对应查询地区为map
        Map<Long, String> areasMap = areas.stream().filter(e -> e.getAreaId() == 1 || (e.getAreaId() == areaId && e.getAreaType() == 2)).collect(Collectors.toMap(SysArea::getAreaId, SysArea::getAreaName));
        defaultJson.put("id", 1L);
        defaultJson.put("index", "s1");// 为避免前端使用树结构出现重复数字数据，增加英文用于区别级别 s=市
        defaultJson.put("label", areasMap.get(1L));
        // 查询地区集合
        JSONArray areaArray = new JSONArray();
        // 地区对象
        JSONObject areaJson = new JSONObject();
        areaJson.put("id", areaId);
        areaJson.put("index", "xq" + areaId);// 为避免前端使用树结构出现重复数字数据，增加英文用于区别级别 xq=县区
        areaJson.put("label", areasMap.get(areaId));

        // 获取地区树结构
        List<SysArea> streets = redisService.getCacheObject(getCacheKey(STREET));
        Map<Long, String> streetsMap = streets.stream().filter(e -> e.getParentId() == areaId).collect(Collectors.toMap(SysArea::getAreaId, SysArea::getAreaName));
        Set<Long> areaIdSet = streetsMap.keySet();
        // 根据参数查询项目信息

        List<GwjBaseCommunity> gwjBaseCommunityList = selectCommunityList(gwjBaseCommunity);
        if (StringUtils.isNull(gwjBaseCommunityList) || gwjBaseCommunityList.size() == 0) {
            // 数据空返回空集合
            return jsonArray;
        }
        Map<Long, List<Map<String, Object>>> communityMap = communityListToMap(gwjBaseCommunityList, "xm");// xm=项目
        // 项目集合
        JSONArray communityJsonArray = new JSONArray();
        // 组装树
        for (Long streetId : areaIdSet) {
            // 获取街道数据
            String streetName = streetsMap.get(streetId);
            JSONObject json = new JSONObject();
            List<Map<String, Object>> streetCommunitys = communityMap.get(streetId);
            if (StringUtils.isEmpty(streetCommunitys) || streetCommunitys.size() == 0) {
                // 空直接跳过
                continue;
            }
            json.put("id", streetId);
            json.put("index", "jd" + streetId);// jd=街道
            json.put("label", streetName);
            json.put("children", streetCommunitys);
            communityJsonArray.add(json);
        }
        // 数据组装 市->县级区->街道
        areaJson.put("children", communityJsonArray);
        areaArray.add(areaJson);
        defaultJson.put("children", areaArray);
        jsonArray.add(defaultJson);
        return jsonArray;
    }

    /**
     * 项目列表转换为streetId Map的List集合
     * 
     * @param gwjBaseCommunityList
     * @param prefix 前缀
     * @return
     */
    private Map<Long, List<Map<String, Object>>> communityListToMap(List<GwjBaseCommunity> gwjBaseCommunityList, String prefix) {
        Map<Long, List<Map<String, Object>>> resultMap = new HashMap<Long, List<Map<String, Object>>>();
        gwjBaseCommunityList.stream().forEach(gbc -> {
            Map<String, Object> map = new HashMap<String, Object>();
            Long streetId = gbc.getStreetId();
            Long communityId = gbc.getCommunityId();
            map.put("id", communityId);
            map.put("label", gbc.getCommunityName());
            map.put("streetId", streetId);
            map.put("communityId", communityId);
            // map.put("communityName", gbc.getCommunityName());
            map.put("index", (StringUtils.isNull(prefix) ? "" : prefix) + communityId);
            // 空则新增
            if (StringUtils.isNull(resultMap.get(streetId))) {
                List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
                list.add(map);
                resultMap.put(streetId, list);
            } else {
                resultMap.get(streetId).add(map);
            }
        });
        return resultMap;
    }

    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @param type 类型
     * @return 缓存键key
     */
    private String getCacheKey(String configKey) {
        return CacheConstants.CAPTCHA_SYS_AREA + configKey;
    }

    /******************* 新增方法保留区 ******************/

    /**
     * 查询基础数据（小区信息）列表
     *
     * @param request 请求
     * @return 基础数据（小区信息）集合
     */
    @Override
    public List<GwjBaseCommunityListDTO> selectCommunityDtoList(GwjBaseCommunityQueryRequest request) {
        return communityMapper.selectCommunityDtoList(request);
    }

    public static void main(String[] args) {
        Map<Long, List<Map<String, Object>>> resultMap = new HashMap<Long, List<Map<String, Object>>>();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", 1);
        map.put("label", 2);
        map.put("streetId", 3);
        resultMap.get("key").add(map);
        System.out.println(resultMap);
    }

}
